/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.statusbar.board;

import android.animation.LayoutTransition;
import android.animation.LayoutTransition.TransitionListener;
import android.animation.TimeInterpolator;
import android.app.ActivityManagerNative;
import android.app.StatusBarManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.FrameLayout;
import android.widget.GridView;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.ImageView;

import com.android.systemui.R;
import com.android.systemui.statusbar.BaseStatusBar;
import com.android.systemui.statusbar.DelegateViewHelper;
import com.android.systemui.statusbar.phone.BarTransitions;
import com.android.systemui.statusbar.board.BoardNavigationBarTransitions;
import com.android.systemui.statusbar.phone.NavigationBarViewTaskSwitchHelper;
import com.android.systemui.statusbar.phone.PhoneStatusBar;
import com.android.systemui.statusbar.policy.DeadZone;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Date;
import java.text.SimpleDateFormat;

import android.widget.Toast;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.graphics.drawable.AnimationDrawable;
import android.content.Intent;

public class BoardNavigationBarView extends LinearLayout {
    final static boolean DEBUG = false;
    final static String TAG = "PhoneStatusBar/BoardNavigationBarView";

    // slippery nav bar when everything is disabled, e.g. during setup
    final static boolean SLIPPERY_WHEN_DISABLED = true;

    final Display mDisplay;
    View mCurrentView = null;
    View[] mRotatedViews = new View[4];

    int mBarSize;
    boolean mVertical;
    boolean mScreenOn;

    boolean mShowMenu;
    int mDisabledFlags = 0;
    int mNavigationIconHints = 0;

    private Drawable mUndoClickableIcon, mUndoUnclickableIcon,
            mRedoClickableIcon, mRedoUnClickableIcon,
            mClearClickableIcon, mClearUnClickableIcon,
            mPushClickableIcon, mPushUnclickable,
            mPullClickable, mPullUnclickable;

    private static final int[][] sICONS = new int[][]{
            {R.drawable.level_0_white, R.drawable.level_1_white, R.drawable.level_2_white},
            {R.drawable.level_0_yellow, R.drawable.level_1_yellow, R.drawable.level_2_yellow},
            {R.drawable.level_0_green, R.drawable.level_1_green, R.drawable.level_2_green},
            {R.drawable.level_0_blue, R.drawable.level_1_blue, R.drawable.level_2_blue},
            {R.drawable.level_0_purple, R.drawable.level_1_purple, R.drawable.level_2_purple},
            {R.drawable.level_0_red, R.drawable.level_1_red, R.drawable.level_2_red},
            {R.drawable.level_0_orange, R.drawable.level_1_orange, R.drawable.level_2_orange},
            {R.drawable.level_0_black, R.drawable.level_1_black, R.drawable.level_2_black}
    };

    private NavigationBarViewTaskSwitchHelper mTaskSwitchHelper;
    private DelegateViewHelper mDelegateHelper;
    private DeadZone mDeadZone;
    private final BoardNavigationBarTransitions mBarTransitions;

    // workaround for LayoutTransitions leaving the nav buttons in a weird state (bug 5549288)
    final static boolean WORKAROUND_INVALID_LAYOUT = true;
    final static int MSG_CHECK_INVALID_LAYOUT = 8686;

    // performs manual animation in sync with layout transitions
    private final NavTransitionListener mTransitionListener = new NavTransitionListener();

    private OnVerticalChangedListener mOnVerticalChangedListener;
    private boolean mIsLayoutRtl;
    private boolean mDelegateIntercepted;

    private class NavTransitionListener implements TransitionListener {
        private boolean mBackTransitioning;
        private boolean mHomeAppearing;
        private long mStartDelay;
        private long mDuration;
        private TimeInterpolator mInterpolator;

        @Override
        public void startTransition(LayoutTransition transition, ViewGroup container,
                                    View view, int transitionType) {
            if (view.getId() == R.id.back) {
                mBackTransitioning = true;
            } else if (view.getId() == R.id.home && transitionType == LayoutTransition.APPEARING) {
                mHomeAppearing = true;
                mStartDelay = transition.getStartDelay(transitionType);
                mDuration = transition.getDuration(transitionType);
                mInterpolator = transition.getInterpolator(transitionType);
            }
        }

        @Override
        public void endTransition(LayoutTransition transition, ViewGroup container,
                                  View view, int transitionType) {
            if (view.getId() == R.id.back) {
                mBackTransitioning = false;
            } else if (view.getId() == R.id.home && transitionType == LayoutTransition.APPEARING) {
                mHomeAppearing = false;
            }
        }
    }

    private final OnClickListener mImeSwitcherClickListener = new OnClickListener() {
        @Override
        public void onClick(View view) {
            ((InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE))
                    .showInputMethodPicker();
        }
    };

    private class H extends Handler {
        public void handleMessage(Message m) {
            switch (m.what) {
                case MSG_CHECK_INVALID_LAYOUT:
                    final String how = "" + m.obj;
                    final int w = getWidth();
                    final int h = getHeight();
                    final int vw = mCurrentView.getWidth();
                    final int vh = mCurrentView.getHeight();

                    if (h != vh || w != vw) {
                        if (WORKAROUND_INVALID_LAYOUT) {
                            requestLayout();
                        }
                    }
                    break;
            }
        }
    }

    public BoardNavigationBarView(Context context, AttributeSet attrs) {
        super(context, attrs);

        mDisplay = ((WindowManager) context.getSystemService(
                Context.WINDOW_SERVICE)).getDefaultDisplay();

        final Resources res = getContext().getResources();
        mBarSize = res.getDimensionPixelSize(R.dimen.board_navigation_button_height);
        mVertical = false;
        mShowMenu = false;
        mDelegateHelper = new DelegateViewHelper(this);
        mTaskSwitchHelper = new NavigationBarViewTaskSwitchHelper(context);

        getIcons(res);

        mBarTransitions = new BoardNavigationBarTransitions(this);
    }

    public BarTransitions getBarTransitions() {
        return mBarTransitions;
    }

    public void setDelegateView(View view) {
        mDelegateHelper.setDelegateView(view);
    }

    public void setBar(BaseStatusBar phoneStatusBar) {
        mTaskSwitchHelper.setBar(phoneStatusBar);
        mDelegateHelper.setBar(phoneStatusBar);
    }

    public void setOnVerticalChangedListener(OnVerticalChangedListener onVerticalChangedListener) {
        mOnVerticalChangedListener = onVerticalChangedListener;
        notifyVerticalChangedListener(mVertical);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        initDownStates(event);
//        dismissDialog();
        if (!mDelegateIntercepted && mTaskSwitchHelper.onTouchEvent(event)) {
            return true;
        }
//        if (mDeadZone != null && event.getAction() == MotionEvent.ACTION_OUTSIDE) {
//            mDeadZone.poke(event);
//        }
        if (mDelegateHelper != null && mDelegateIntercepted) {
            boolean ret = mDelegateHelper.onInterceptTouchEvent(event);
            if (ret) return true;
        }
        return super.onTouchEvent(event);
    }

    private void initDownStates(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            mDelegateIntercepted = false;
        }
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        initDownStates(event);
        boolean intercept = mTaskSwitchHelper.onInterceptTouchEvent(event);
        if (!intercept) {
            mDelegateIntercepted = mDelegateHelper.onInterceptTouchEvent(event);
            intercept = mDelegateIntercepted;
        } else {
            MotionEvent cancelEvent = MotionEvent.obtain(event);
            cancelEvent.setAction(MotionEvent.ACTION_CANCEL);
            mDelegateHelper.onInterceptTouchEvent(cancelEvent);
            cancelEvent.recycle();
        }
        return intercept;
    }

    private H mHandler = new H();

    public View getCurrentView() {
        return mCurrentView;
    }

    public View getUndoButton() {
        return mCurrentView.findViewById(R.id.board_undo);
    }

    public View getRedoButton() {
        return mCurrentView.findViewById(R.id.board_redo);
    }

    public View getMathButton() {
        return mCurrentView.findViewById(R.id.board_math);
    }

    public View getPaintButton() {
        return mCurrentView.findViewById(R.id.board_paint);
    }

    public LongPressImageView getPullButton() {
        return (LongPressImageView) mCurrentView.findViewById(R.id.board_pull);
    }

    public LongPressImageView getPushButton() {
        return (LongPressImageView) mCurrentView.findViewById(R.id.board_push);
    }

    public View getClearButton() {
        return mCurrentView.findViewById(R.id.board_clear);
    }

    public View getRecordButton() {
        return recordButton;
    }

    public View getSettingButton() {
        return mCurrentView.findViewById(R.id.board_setting);
    }

    public View getVideoControllerView() {
        return mCurrentView.findViewById(R.id.ll_video_controller);
    }

    public View getBrowserControllerView() {
        return mCurrentView.findViewById(R.id.ll_browser_controller);
    }

    public View getVideoControllerButton() {
        return mCurrentView.findViewById(R.id.board_video_controller);
    }

    public View getVideoREWButton() {
        return mCurrentView.findViewById(R.id.board_video_rew);
    }

    public View getVideoFFButton() {
        return mCurrentView.findViewById(R.id.board_video_ff);
    }

    public View getVideoVolumeButton() {
        return mCurrentView.findViewById(R.id.board_video_volume);
    }

    public ImageView getVideoImageView() {
        return ((ImageView) mCurrentView.findViewById(R.id.img_video_status));
    }

    public TextView getVideoDurationView() {
        return (TextView) mCurrentView.findViewById(R.id.tv_video_duration);
    }

    public ImageView getVideoLoopView() {
        return (ImageView) mCurrentView.findViewById(R.id.iv_video_loop);
    }

    public View getDocControllerView() {
        return mCurrentView.findViewById(R.id.ll_document_control);
    }

    public View getDocPreButton() {
        return mCurrentView.findViewById(R.id.img_document_pre);
    }

    public View getDocNextButton() {
        return mCurrentView.findViewById(R.id.img_document_next);
    }

    public TextView getDocPageView() {
        return (TextView) mCurrentView.findViewById(R.id.tv_document_page);
    }

    public View getDocLoopView() {
        return mCurrentView.findViewById(R.id.iv_doc_loop);
    }

    public TextView getDownloadView() {
        return (TextView) mCurrentView.findViewById(R.id.tv_download);
    }

    public ImageView getDocImageView() {
        return ((ImageView) mCurrentView.findViewById(R.id.img_document_control));
    }

    public View getProjectionView() {
        return mCurrentView.findViewById(R.id.ll_projection_controller);
    }

    public View getProjectionVolume() {
        return mCurrentView.findViewById(R.id.board_projection_volume);
    }

    public ImageView getProjectionImageView() {
        return (ImageView) mCurrentView.findViewById(R.id.img_screen_projection);
    }

    public TextView getProjectionTextView() {
        return (TextView) mCurrentView.findViewById(R.id.tv_screen_projection_description);
    }

    public ImageView getBrowserStatus() {
        return (ImageView) mCurrentView.findViewById(R.id.img_browser_status);
    }

    public ImageView getBrowserPre() {
        return (ImageView) mCurrentView.findViewById(R.id.board_browser_pre);
    }

    public ImageView getBrowserNext() {
        return (ImageView) mCurrentView.findViewById(R.id.board_browser_next);
    }

    public ImageView getBrowserRefresh() {
        return (ImageView) mCurrentView.findViewById(R.id.board_browser_refresh);
    }

    public ImageView getBrowserHome() {
        return (ImageView) mCurrentView.findViewById(R.id.board_browser_home);
    }

    public ImageView getBrowserLink() {
        return (ImageView) mCurrentView.findViewById(R.id.board_browser_link);
    }

    private void getIcons(Resources res) {
        mUndoClickableIcon = res.getDrawable(R.drawable.icon_undo_clickable);
        mUndoUnclickableIcon = res.getDrawable(R.drawable.icon_undo_unclickable);
        mRedoClickableIcon = res.getDrawable(R.drawable.icon_redo_clickable);
        mRedoUnClickableIcon = res.getDrawable(R.drawable.icon_redo_unclickable);
        mClearClickableIcon = res.getDrawable(R.drawable.icon_clear_clickable);
        mClearUnClickableIcon = res.getDrawable(R.drawable.icon_clear_unclickable);
        mPushClickableIcon = res.getDrawable(R.drawable.icon_push_clickable);
        mPushUnclickable = res.getDrawable(R.drawable.icon_push_unclickable);
        mPullClickable = res.getDrawable(R.drawable.icon_pull_clickable);
        mPullUnclickable = res.getDrawable(R.drawable.icon_pull_unclickable);
    }

    public void refreshPaintButtonStatus(int colorIndex, int levelIndex) {
        if (colorIndex > sICONS.length - 1) {    //橡皮擦
            ((ImageView) getPaintButton()).setImageResource(R.drawable.level_no_eraser);
        } else {
            ((ImageView) getPaintButton()).setImageResource(sICONS[colorIndex][levelIndex]);
        }
    }

    public void refreshButtonStatus(boolean undoClickable, boolean redoClickable,
                                    boolean mathClickable, boolean clearClickable,
                                    boolean pushClickable, boolean pullClickable) {
        getUndoButton().setClickable(undoClickable);
        ((ImageView) getUndoButton()).setImageDrawable(undoClickable ? mUndoClickableIcon : mUndoUnclickableIcon);
        getRedoButton().setClickable(redoClickable);
        ((ImageView) getRedoButton()).setImageDrawable(redoClickable ? mRedoClickableIcon : mRedoUnClickableIcon);
        ((ImageView) getClearButton()).setImageDrawable(clearClickable ? mClearClickableIcon : mClearUnClickableIcon);
        getPushButton().setClickable(pushClickable);
        ((ImageView) getPushButton()).setImageDrawable(pushClickable ? mPushClickableIcon : mPushUnclickable);
        getPullButton().setClickable(pullClickable);
        ((ImageView) getPullButton()).setImageDrawable(pullClickable ? mPullClickable : mPullUnclickable);
    }

    public void setVideoLayoutVisible(int visibility) {
        getVideoLoopView().setVisibility(View.GONE);
        if (visibility == View.VISIBLE) {
            getDocControllerView().setVisibility(View.GONE);
            getProjectionView().setVisibility(View.GONE);
            setVideoStatus(true);
        }
        getVideoControllerView().setVisibility(visibility);
    }

    public void setBrowserLayoutVisible(int visible) {
        getBrowserControllerView().setVisibility(visible);
        getBrowserLink().setVisibility(isShowLink() ? VISIBLE : INVISIBLE);
        getBrowserStatus().setImageResource(R.drawable.icon_screen_playing);
    }

    public boolean isShowLink() {
        boolean visible = true;
        try {
            Context boardContext = mContext.createPackageContext(
                    "com.w2here.board", Context.CONTEXT_IGNORE_SECURITY);
            SharedPreferences boardSp = boardContext.getSharedPreferences("hhapp_base_cache",
                    Context.MODE_MULTI_PROCESS);
            visible = boardSp.getBoolean("browser_link_visible", true);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return visible;
    }

    public void setVideoStatus(boolean isPlaying) {
        if (isPlaying) {
            getVideoImageView().setImageResource(R.drawable.icon_screen_playing);
            ((ImageView) getVideoControllerButton()).setImageResource(R.drawable.icon_video_pause);
        } else {
            getVideoImageView().setImageResource(R.drawable.board_in_playing);
            anim = (AnimationDrawable) getVideoImageView().getDrawable();
            getVideoImageView().post(new Runnable() {
                @Override
                public void run() {
                    anim.start();
                }
            });
            ((ImageView) getVideoControllerButton()).setImageResource(R.drawable.icon_video_play);
        }
        getVideoREWButton().setEnabled(isPlaying);
        getVideoFFButton().setEnabled(isPlaying);

    }

    public void setVideoDuration(String duration) {
        getVideoDurationView().setVisibility(View.VISIBLE);
        getVideoDurationView().setText(duration);
    }

    AnimationDrawable anim;

    public void setDocLayoutVisible(int visibility) {
        getDocLoopView().setVisibility(View.GONE);
        if (visibility == View.VISIBLE) {
            getVideoControllerView().setVisibility(View.GONE);
            getProjectionView().setVisibility(View.GONE);
            getDocImageView().setImageResource(R.drawable.icon_screen_playing);
        } else {
            updateDocPage("00/00");
        }
        getDocControllerView().setVisibility(visibility);
    }

    public void updateDocPage(String page) {
        if (getDocPageView().getVisibility() == View.GONE)
            getDocPageView().setVisibility(View.VISIBLE);
        getDocPageView().setText(page);
    }

    public void setDownloadText(int visibility, String text) {
        if (getDownloadView().getVisibility() == View.GONE)
            getDownloadView().setVisibility(View.VISIBLE);
        getDownloadView().setText(text);
    }

    public void setProjectionView(int visibility, String text, boolean volume) {
        Log.e("MSU", " setProjectionView visibility =" + visibility);
        if (visibility == View.VISIBLE) {
            getVideoControllerView().setVisibility(View.GONE);
            getDocControllerView().setVisibility(View.GONE);
            getProjectionTextView().setText(text);
            getProjectionImageView().setImageResource(R.drawable.icon_screen_playing);
        }
        getProjectionView().setVisibility(visibility);
        getProjectionVolume().setVisibility(volume ? View.VISIBLE : View.GONE);
    }

    public void setProjectionView(String type, boolean isStop) {
        if (TextUtils.equals("projection", type)) {
            if (isStop) {
//                showProjectionTip();
                getProjectionImageView().setImageResource(R.drawable.board_in_projection);
                anim = (AnimationDrawable) getProjectionImageView().getDrawable();
                getProjectionImageView().post(new Runnable() {
                    @Override
                    public void run() {
                        anim.start();
                    }
                });
            } else
                getProjectionImageView().setImageResource(R.drawable.icon_screen_playing);
        } else if (TextUtils.equals("doc", type)) {
            if (isStop) {
                getDocImageView().setImageResource(R.drawable.board_in_playing);
                anim = (AnimationDrawable) getDocImageView().getDrawable();
                getDocImageView().post(new Runnable() {
                    @Override
                    public void run() {
                        anim.start();
                    }
                });
            } else
                getDocImageView().setImageResource(R.drawable.icon_screen_playing);
        }
    }

    @Override
    public void setLayoutDirection(int layoutDirection) {
        getIcons(getContext().getResources());
        super.setLayoutDirection(layoutDirection);
    }

    public void notifyScreenOn(boolean screenOn) {
        mScreenOn = screenOn;
        setDisabledFlags(mDisabledFlags, true);
    }

    public void setNavigationIconHints(int hints) {
        setNavigationIconHints(hints, false);
    }

    public void setNavigationIconHints(int hints, boolean force) {
        if (!force && hints == mNavigationIconHints) return;
        mNavigationIconHints = hints;

//        ((ImageView) getRecentsButton()).setImageDrawable(mVertical ? mRecentLandIcon : mRecentIcon);

        // Update menu button in case the IME state has changed.
        setMenuVisibility(mShowMenu, true);
        setDisabledFlags(mDisabledFlags, true);
    }

    public void setDisabledFlags(int disabledFlags) {
        setDisabledFlags(disabledFlags, false);
    }

    public void setDisabledFlags(int disabledFlags, boolean force) {
        if (!force && mDisabledFlags == disabledFlags) return;

        mDisabledFlags = disabledFlags;

//        final boolean disableHome = ((disabledFlags & View.STATUS_BAR_DISABLE_HOME) != 0);
//        boolean disableRecent = ((disabledFlags & View.STATUS_BAR_DISABLE_RECENT) != 0);
//        final boolean disableBack = ((disabledFlags & View.STATUS_BAR_DISABLE_BACK) != 0)
//                && ((mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) == 0);
//        final boolean disableSearch = ((disabledFlags & View.STATUS_BAR_DISABLE_SEARCH) != 0);

//        if (SLIPPERY_WHEN_DISABLED) {
//            setSlippery(disableHome && disableRecent && disableBack && disableSearch);
//        }

//        ViewGroup navButtons = (ViewGroup) mCurrentView.findViewById(R.id.nav_buttons);
//        if (navButtons != null) {
//            LayoutTransition lt = navButtons.getLayoutTransition();
//            if (lt != null) {
//                if (!lt.getTransitionListeners().contains(mTransitionListener)) {
//                    lt.addTransitionListener(mTransitionListener);
//                }
//                if (!mScreenOn && mCurrentView != null) {
//                    lt.disableTransitionType(LayoutTransition.CHANGE_APPEARING |
//                            LayoutTransition.CHANGE_DISAPPEARING |
//                            LayoutTransition.APPEARING |
//                            LayoutTransition.DISAPPEARING);
//                }
//            }
//        }
//        if (inLockTask() && disableRecent && !disableHome) {
//            // Don't hide recents when in lock task, it is used for exiting.
//            // Unless home is hidden, then in DPM locked mode and no exit available.
//            disableRecent = false;
//        }
        mBarTransitions.applyBackButtonQuiescentAlpha(mBarTransitions.getMode(), true /*animate*/);
    }

    private boolean inLockTask() {
        try {
            return ActivityManagerNative.getDefault().isInLockTaskMode();
        } catch (RemoteException e) {
            return false;
        }
    }

    private void setVisibleOrGone(View view, boolean visible) {
        if (view != null) {
            view.setVisibility(visible ? VISIBLE : GONE);
        }
    }

    public void setSlippery(boolean newSlippery) {
        WindowManager.LayoutParams lp = (WindowManager.LayoutParams) getLayoutParams();
        if (lp != null) {
            boolean oldSlippery = (lp.flags & WindowManager.LayoutParams.FLAG_SLIPPERY) != 0;
            if (!oldSlippery && newSlippery) {
                lp.flags |= WindowManager.LayoutParams.FLAG_SLIPPERY;
            } else if (oldSlippery && !newSlippery) {
                lp.flags &= ~WindowManager.LayoutParams.FLAG_SLIPPERY;
            } else {
                return;
            }
            WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
            wm.updateViewLayout(this, lp);
        }
    }

    public void setMenuVisibility(final boolean show) {
        setMenuVisibility(show, false);
    }

    public void setMenuVisibility(final boolean show, final boolean force) {
        if (!force && mShowMenu == show) return;

        mShowMenu = show;

        // Only show Menu if IME switcher not shown.
        final boolean shouldShow = mShowMenu &&
                ((mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_IME_SHOWN) == 0);
    }

    @Override
    public void onFinishInflate() {
        mRotatedViews[Surface.ROTATION_0] =
                mRotatedViews[Surface.ROTATION_180] = findViewById(R.id.rot0);

        mRotatedViews[Surface.ROTATION_90] =
                mRotatedViews[Surface.ROTATION_270] = findViewById(R.id.rot90);

        mCurrentView = mRotatedViews[Surface.ROTATION_0];

        updateRTLOrder();

    }

    public boolean isVertical() {
        return mVertical;
    }

    public void reorient() {
        final int rot = mDisplay.getRotation();
        for (int i = 0; i < 4; i++) {
            mRotatedViews[i].setVisibility(View.GONE);
        }
        mCurrentView = mRotatedViews[rot];

        mCurrentView.setVisibility(View.VISIBLE);

//        mDeadZone = (DeadZone) mCurrentView.findViewById(R.id.deadzone);

        tvRecordTime = (TextView) mCurrentView.findViewById(R.id.tv_record);
        llRecordControl = (LinearLayout) mCurrentView.findViewById(R.id.ll_record);
        recordButton = (ImageView) mCurrentView.findViewById(R.id.board_record);

        // force the low profile & disabled states into compliance
        mBarTransitions.init(mVertical);
        setDisabledFlags(mDisabledFlags, true /* force */);
        setMenuVisibility(mShowMenu, true /* force */);

        // swap to x coordinate if orientation is not in vertical
        if (mDelegateHelper != null) {
            mDelegateHelper.setSwapXY(mVertical);
        }
        updateTaskSwitchHelper();

        setNavigationIconHints(mNavigationIconHints, true);
    }

    private void updateTaskSwitchHelper() {
        boolean isRtl = (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL);
        mTaskSwitchHelper.setBarState(mVertical, isRtl);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        mDelegateHelper.setInitialTouchRegion(getMathButton(), getPaintButton(), getClearButton());
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        final boolean newVertical = w > 0 && h > w;
        if (newVertical != mVertical) {
            mVertical = newVertical;
            reorient();
            notifyVerticalChangedListener(newVertical);
        }

        postCheckForInvalidLayout("sizeChanged");
        super.onSizeChanged(w, h, oldw, oldh);
    }

    private void notifyVerticalChangedListener(boolean newVertical) {
        if (mOnVerticalChangedListener != null) {
            mOnVerticalChangedListener.onVerticalChanged(newVertical);
        }
    }

    @Override
    protected void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
//        updateRTLOrder();
        updateTaskSwitchHelper();
    }

    /**
     * In landscape, the LinearLayout is not auto mirrored since it is vertical. Therefore we
     * have to do it manually
     */
    private void updateRTLOrder() {
        boolean isLayoutRtl =
                getResources().getConfiguration().getLayoutDirection() == LAYOUT_DIRECTION_RTL;
        if (mIsLayoutRtl != isLayoutRtl) {

            // We swap all children of the 90 and 270 degree layouts, since they are vertical
            View rotation90 = mRotatedViews[Surface.ROTATION_90];
//            swapChildrenOrderIfVertical(rotation90.findViewById(R.id.nav_buttons));
            adjustExtraKeyGravity(rotation90, isLayoutRtl);

            View rotation270 = mRotatedViews[Surface.ROTATION_270];
            if (rotation90 != rotation270) {
//                swapChildrenOrderIfVertical(rotation270.findViewById(R.id.nav_buttons));
                adjustExtraKeyGravity(rotation270, isLayoutRtl);
            }
            mIsLayoutRtl = isLayoutRtl;
        }
    }

    private void adjustExtraKeyGravity(View navBar, boolean isLayoutRtl) {
        View menu = navBar.findViewById(R.id.menu);
        View imeSwitcher = navBar.findViewById(R.id.ime_switcher);
        if (menu != null) {
            FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) menu.getLayoutParams();
            lp.gravity = isLayoutRtl ? Gravity.BOTTOM : Gravity.TOP;
            menu.setLayoutParams(lp);
        }
        if (imeSwitcher != null) {
            FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) imeSwitcher.getLayoutParams();
            lp.gravity = isLayoutRtl ? Gravity.BOTTOM : Gravity.TOP;
            imeSwitcher.setLayoutParams(lp);
        }
    }

    private void postCheckForInvalidLayout(final String how) {
        mHandler.obtainMessage(MSG_CHECK_INVALID_LAYOUT, 0, 0, how).sendToTarget();
    }

    private static String visibilityToString(int vis) {
        switch (vis) {
            case View.INVISIBLE:
                return "INVISIBLE";
            case View.GONE:
                return "GONE";
            default:
                return "VISIBLE";
        }
    }

    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {

    }

    private Runnable mUpdateRecordTimeRunable;
    private SimpleDateFormat mRecordDateFormat;
    private TextView tvRecordTime;
    private LinearLayout llRecordControl;
    private ImageView recordButton;

    public Intent recordStatusChange(Intent intent) {
        if (intent == null) {
            intent = new Intent("com.w2here.board.click");
            intent.putExtra("view", "record");
        }
        if (MediaProjectionUtil.getInstance(mContext).isRunning()) {
            intent.putExtra("status", "start");
            MediaProjectionUtil.getInstance(mContext).stopRecord();
            closeScreenRecord();
            Toast.makeText(mContext, mContext.getString(R.string.screen_record_finish_tip), Toast.LENGTH_SHORT).show();
        } else {
            boolean recordSuccessful = MediaProjectionUtil.getInstance(mContext).startRecord();
            if (recordSuccessful) {
                intent.putExtra("status", "stop");
                openScreenRecord();
                Toast.makeText(mContext, mContext.getString(R.string.screen_record_start_tip), Toast.LENGTH_SHORT).show();
            }
        }
        return intent;
    }

    public void recordStatusChange(boolean isStart) {
        if (isStart) {
            if (!MediaProjectionUtil.getInstance(mContext).isRunning()) {
                boolean recordSuccessful = MediaProjectionUtil.getInstance(mContext).startRecord();
                if (recordSuccessful) {
                    openScreenRecord();
                }
            }
        } else {
            if (MediaProjectionUtil.getInstance(mContext).isRunning()) {
                MediaProjectionUtil.getInstance(mContext).stopRecord();
                closeScreenRecord();
            }
        }
    }

    /**
     * 开始屏幕录制
     */
    public void openScreenRecord() {
        recordButton.setImageResource(R.drawable.icon_record_stop);
        tvRecordTime.setVisibility(VISIBLE);
        recordButton.setClickable(false);

        mRecordDateFormat = new SimpleDateFormat("mm:ss");

        final long currentTimeMillis = System.currentTimeMillis();

        mUpdateRecordTimeRunable = new Runnable() {
            @Override
            public void run() {
                tvRecordTime.setVisibility(VISIBLE);
                tvRecordTime.setText(mRecordDateFormat.format(
                        new Date(System.currentTimeMillis() - currentTimeMillis)));
                llRecordControl.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        tvRecordTime.setVisibility(GONE);
                    }
                }, 500);
                llRecordControl.postDelayed(this, 1000);
            }
        };
        llRecordControl.post(mUpdateRecordTimeRunable);
        llRecordControl.postDelayed(new Runnable() {
            @Override
            public void run() {
                recordButton.setClickable(true);
            }
        }, 1500);
    }

    /**
     * 关闭屏幕录制
     */
    public void closeScreenRecord() {
        recordButton.setImageResource(R.drawable.icon_record_begin);
        tvRecordTime.setVisibility(GONE);

        llRecordControl.removeCallbacks(mUpdateRecordTimeRunable);

        mUpdateRecordTimeRunable = null;
        mRecordDateFormat = null;
    }

    ChoosePaintDialog choosePaintDialog;
    SettingDialog settingDialog;
    RegisterDialog registerDialog;

    public ChoosePaintDialog getChoosePaintDialog() {
        if (choosePaintDialog == null)
            choosePaintDialog = new ChoosePaintDialog(mContext, (ImageView) getPaintButton());
        return choosePaintDialog;
    }

    public SettingDialog getSettingDialog() {
        if (settingDialog == null)
            settingDialog = new SettingDialog(mContext);
        return settingDialog;
    }

    public RegisterDialog getRegisterDialog() {
        if (registerDialog == null)
            registerDialog = new RegisterDialog(mContext);
        return registerDialog;
    }

    public void showChoosePaint() {
        getChoosePaintDialog().show();
    }

    public void showSetting() {
        getSettingDialog().show();
    }

    public void showRegister() {
        getRegisterDialog().show();
    }

    public void dismissDialog() {
        if (BaseDialog.sCurrentShowPopup != null) {
            BaseDialog.sCurrentShowPopup.dismiss();
            BaseDialog.sCurrentShowPopup = null;
        }
    }

    public void cancelPullPushScroll() {
        getPushButton().cancel();
        getPullButton().cancel();
    }

    public void showTip(int type) {
        if (type == -1) {
            return;
        }
        View toastRoot = LayoutInflater.from(mContext).inflate(R.layout.board_toast, null);
        Toast toast = new Toast(mContext);
        toast.setView(toastRoot);
        toast.setDuration(Toast.LENGTH_LONG);
        TextView tv = (TextView) toastRoot.findViewById(R.id.tv_toast);
        if (type == 0)
            tv.setText(mContext.getString(R.string.freeze_cast_tip));
        else if (type == 1)
            tv.setText(mContext.getString(R.string.clear_cast_back_tip));
        else if (type == 2)
            tv.setText(mContext.getString(R.string.freeze_play_tip));
        else if (type == 3)
            tv.setText(mContext.getString(R.string.clear_play_back_tip));
        else if (type == 4)
            tv.setText(mContext.getString(R.string.freeze_web_tip));
        else if (type == 5)
            tv.setText(mContext.getString(R.string.clear_web_back_tip));
        int width = mDisplay.getWidth();
        if (mDisplay.getRotation() == Surface.ROTATION_0
                || mDisplay.getRotation() == Surface.ROTATION_180) {
            toast.setGravity(Gravity.BOTTOM | Gravity.LEFT, width / 60, 0);
        } else {
            toast.setGravity(Gravity.BOTTOM | Gravity.LEFT, width / 40, 90);
        }
        toast.show();
    }

    public void reset() {
        cancelPullPushScroll();
        dismissDialog();
        getVideoControllerView().setVisibility(View.GONE);
        getDocControllerView().setVisibility(View.GONE);
        getProjectionView().setVisibility(View.GONE);
        getDownloadView().setVisibility(View.GONE);
        getBrowserControllerView().setVisibility(View.GONE);
        refreshButtonStatus(false, false, true, false, true, false);
    }

    public void setVideoLoopVisibility(boolean visibility, String type) {
        if (TextUtils.equals("videoController", type)) {
            getVideoLoopView().setVisibility(visibility ? View.VISIBLE : View.GONE);
        } else if (TextUtils.equals("documentControl", type)) {
            getDocLoopView().setVisibility(visibility ? View.VISIBLE : View.GONE);
        }
    }

    public interface OnVerticalChangedListener {
        void onVerticalChanged(boolean isVertical);
    }

}
